define(function(require, exports, module) {
    'use strict';
    
    var rk = require('rk');


    //该service负责渲染自定义编辑框等
    (function() {
        var formService = {};
        var me = formService;
        var PLS_SELECT = rk.i18n('W_PLS_SELECT');
        var itemsCache = {};
        var conElem = null;
        var domType = 'li'; //li*, div
        me.cacheItemInfo = function(items){
            for (var i = 0, len = items.length; i < len; i++) {
                var item = items[i];
                var must = (item.mustEnterFlg == '1');
                item.must = must;
                item.isCurrency = (item.currencyFlg === 1);
                itemsCache[item.id + ''] = item;
            }
        };
        me.setDomType = function(type) {
            domType = type;
        };
        var currencyUnit = SESSION.currencyUnit;
        me.drawForm = function(elem, items, entity) {
            if (typeof entity == 'undefined') entity = null;
            conElem = elem;
            me.cacheItemInfo(items);
            if (domType == 'div') {
                renderHTML_1(items);
            } else {
                renderHTML_2(items);
            }
            createWidgets(entity);
        };
        var renderHTML_1 = function(items) {
            // var me = this;
            // var elem = me.element;            
            var html = '';
            for (var i = 0, len = items.length; i < len; i++) {
                var item = itemsCache[items[i].id+''];
                var editorHtml = getHtml(item);
                if (!editorHtml) continue;
                html = html + '<div class="report_content_div rk-formrow" refId="' + item.id + '" wtype="' + item.itemTypeEntry + '">' + (!item.noTitle ? '<span class="field_item">' + item.itemName + (item.isCurrency ? '(' + currencyUnit + ')' : '') + (item.must ? '<span class="mandatory_symbol">*</span>' : '') + '</span>' : '') + editorHtml + '</div>';
            }
            conElem.html(html);
        };
        var renderHTML_2 = function(items) {
            // var me = this;
            // var elem = me.element;
            var html = '';
            for (var i = 0, len = items.length; i < len; i++) {
                var item = itemsCache[items[i].id+''];
                var editorHtml = getHtml(item);
                if(item.itemTypeEntry == 8) continue;
                if (!editorHtml) continue;
                html = html + '<li class="rk-formrow" refId="' + item.id + '" wtype="' + item.itemTypeEntry + '">' + (!item.noTitle ? '<label>' + item.itemName + (item.isCurrency ? '(' + currencyUnit + ')' : '') + '</label>' : '') + editorHtml + (item.must ? '<span class="mandatory_symbol">*</span>' : '') + '</li>';
                itemsCache[item.id + ''] = item;
            }
            conElem.html('<ul class="pop_list crate-entity-list crate-approval-list">' + html + '</ul>');
        };
        var createWidgets = function(entity) {
            var children;
            if (domType == 'div') {
                children = conElem.children();
            } else {
                children = conElem.find('ul > li');
            }
            children.each(function(i, el) {
                el = $(el);
                var wtype = el.attr('wtype');
                if (wtype) {
                    createOneWidget(wtype, el, entity);
                }
            });
        };
        me._getValueHtml = function (itemValue, item) {
            // 1:文本型 2:文本区型 3:单一选择型(下拉,radio) 4:多项选择型 5:整数型 6:实数型 7:日期
            if (item.itemTypeEntry == 7) {
                itemValue = itemValue ? Globalize.format(new Date(itemValue - 0), item.dateMode == 2 ? 'yyyy-MM-dd HH:mm' : 'yyyy-MM-dd') : itemValue;
            } else if (item.itemTypeEntry == 3) {
                itemValue = (itemValue && item.values[itemValue]) ? item.values[itemValue].name : itemValue;
            } else if (item.itemTypeEntry == 4) {
                itemValue = (itemValue.length > 0) ? $.map(itemValue, function(o, i2) {
                    return item.values[o].name;
                }).join(',') : itemValue;
            } else if (item.itemTypeEntry == 2) {
                itemValue = itemValue ? itemValue.replace(/\n/g, '<br>') : itemValue;
            } else if (item.itemTypeEntry == 6) {
                if (item.currencyFlg == '1' && itemValue != '') {
                    itemValue = itemValue + SESSION.currencyUnit;
                }
            }
            return itemValue;
        }
        var createOneWidget = function(wtype, el, entity, opt) {
            var refId = el.attr('refId');
            var itemInfo = itemsCache[refId + ''];
            if(typeof opt == 'undefined') opt = {};

            var isEdit = (entity ? true : false);
            var key = itemInfo.entryPropertyNameOnly;
            var value;
            if (isEdit) { //is edit
                if (itemInfo.entryPropertyName.indexOf('product.') >= 0 ) {
                    value = entity._op && entity._op[key];
                    if (value != null && value != '') {
                        el.find('span').attr('title', value).text(value);
                        return;
                    }
                    value = entity._p && entity._p[key];
                    value = (value == null ? '' : value);
                    var valueHtml = me._getValueHtml(value, itemInfo);
                    el.find('span').attr('title', valueHtml).text(valueHtml);
                    return;
                }
                value = entity[key];
                value = (value === null ? '' : value);
            }
            if (itemInfo.entryPropertyName.indexOf('product.') >= 0 ) {
                value = entity._p && entity._p[key];
                value = (value == null ? '' : value);
                var valueHtml = me._getValueHtml(value, itemInfo);
                el.find('span').attr('title', valueHtml).text(valueHtml);
                return;
            }
            var renderFn = render['type_' + wtype];
            if (!renderFn) {
                renderFn = render.type_default;
            }
            (renderFn)(el, itemInfo, isEdit, value, opt);
        };
        me.createOneWidget = function(){
            createOneWidget.apply(this, arguments);
        };

        var TMPL = require('oa/tmpl/autoForm/itemTypeEntry');
        var getHtml = function(item) {
            if (item.entryPropertyName.indexOf('product.') >= 0) {
                return '<span class="cell-product cell-text"></span>';
            } else {
                return rk.templateText(TMPL[item.itemTypeEntry] || TMPL[0] || '', item);
            }
        };

        me.getHtml  = function(item){
            return getHtml(item);
        }

        var render = {};
        render.type_default = function(el, itemInfo, isEdit, value, opt) {
            var obj = el.find('input, textarea');
            if (isEdit) obj.val(value);
            if(opt.width)obj.width(opt.width);
        };
        render.type_3 = function(el, itemInfo, isEdit, value, opt) {
            if(!el.find('select').find('option[selected="selected"]').size()) {
                el.find('select').val(null);
            }
            if (isEdit) {
                el.find('option[value="' + value + '"]').prop('selected', true)
            }
            el.find('select').selectmenu({
                appendTo: 'body'
            });
            if(opt.width)el.find('.ui-selectmenu-button').attr('style','width:'+opt.width+'px !important');
        };
        render.type_4 = function(el, itemInfo, isEdit, value, opt) {
            var wtype_name = 'multiselect';
            var selectObj = el.find('select');
            selectObj[wtype_name]({
                minWidth: opt.width,
                noneSelectedText: PLS_SELECT,
                header: false,
                selectedList: 999, // 0-based index
                checkAllText: rk.i18n('SELECTALL'),
                uncheckAllText: rk.i18n('UNSELECTALL')
            });
            selectObj[wtype_name]('uncheckAll');
            el.attr('wtype-name', wtype_name);

            if(opt.width)el.find('button.ui-multiselect').attr('style','width:'+opt.width+'px !important');
            if ($.isArray(value))
                if (isEdit && value.length > 0) {
                    var map = [];
                    for (var i = 0; i < value.length; i++) {
                        var v = '' + $.trim(value[i]);
                        map[v] = true;
                    }
                    var checkboxes = selectObj[wtype_name]("widget").find(":checkbox");
                    checkboxes.each(function() {
                        var chk = $(this);
                        var cv = chk.attr('value');
                        if (map[cv]) chk.click();
                    });
                }

        };
        render.type_5 = function(el, itemInfo, isEdit, value, opt) {
            var wtype_name = 'numberInput';
            var ipt = el.find('>input');
            ipt[wtype_name]({
                numberFormat: 'n2'
            }).numberInputPlus({
                type: 'integer',
                width: opt.width
            });
            el.attr('wtype-name', wtype_name);
            if (isEdit) {
                ipt.numberInputPlus('setValue', value);
                //el.find('input').val(value);
            }
        };
        render.type_6 = function(el, itemInfo, isEdit, value, opt) {
            var wtype_name = 'numberInput';
            var ipt = el.find('>input');
            ipt[wtype_name]({
                numberFormat: 'n2'
            }).numberInputPlus({
                type: 'float',
                resolution: itemInfo.resolution,
                isCurrency: itemInfo.isCurrency,
                width: opt.width
            });
            el.attr('wtype-name', wtype_name);
            if (isEdit) {
                ipt.numberInputPlus('setValue', value);
                //el.find('input').val(value);
            }
        };
        render.type_7 = function(el, itemInfo, isEdit, value, opt) {
            var wtype_name = 'datepicker';
            el.find('input[act="datepicker"]').datepicker({
                dateFormat: 'yy-mm-dd',
                /* fix buggy IE focus functionality */
                fixFocusIE: false,

                /* blur needed to correctly handle placeholder text */
                onSelect: function(dateText, inst) {
                    this.fixFocusIE = true;
                    $(this).blur().change().focus();
                },
                onClose: function(dateText, inst) {
                    this.fixFocusIE = true;
                    this.focus();
                },
                beforeShow: function(input, inst) {
                    var result = rk.isIE ? !this.fixFocusIE : true;
                    this.fixFocusIE = false;
                    return result;
                }
            }).attr("readOnly", true);

            var timepicker = el.find('input[act="timepicker"]');
            if (timepicker.size() > 0) {
                timepicker.timepicker({
                    onSelect: function(time, inst) {
                        var time = time;
                    }
                }).attr("readOnly", true);;
            }

            el.attr('wtype-name', wtype_name);
            if (isEdit && value) {
                var mom = moment(parseFloat(value));
                //日期
                el.find('input[act="datepicker"]').val(mom.format('YYYY-MM-DD'));
                //时间
                if (timepicker.size() > 0) {
                    var timeStr = mom.format('HH:mm');
                    timepicker.val(timeStr);
                }
            }
        };
        render.type_attachment = function(el, itemInfo, isEdit, value, opt) {
            //什么也不做，仅生成div壳，由外界自行初始化
        };

        //////////////////////////////////////
        var errMessages = [];
        me.getFormData = function(elem, validateFn, getDataAnyway) {
            if (typeof getDataAnyway == 'undefined') getDataAnyway = false;
            conElem = elem;
            var data = [];
            errMessages = [];
            var isOk = true;

            var children;
            if (conElem.find('li[wtype]').size() == 0) {
                children = conElem.children('[wtype]');
            } else {
                children = conElem.find('li[wtype]');
            }

            children.each(function(i, el) {
                el = $(el);
                var refId = el.attr('refId');

                //alert(refId)
                var itemInfo = itemsCache[refId + ''];
                var wtype = el.attr('wtype');
                var key = el.attr('key');
                var must = itemInfo.must;
                var val;

                if (wtype) {
                    val = me.getWidgetData(el, wtype);
                    if (!getDataAnyway)
                    //是多组数据val
                        if ($.isArray(val) && val.length > 0) {
                            for (var i = 0, len = val.length; i < len; i++) {
                                var v = val[i].val;
                                if (!validate(refId, wtype, v)) {
                                    isOk = false;
                                    break;
                                }
                            }
                        } else {
                            if (!validate(refId, wtype, val)) {
                                isOk = false;
                                //return false;
                            }
                        }
                    if ($.isFunction(validateFn)) {
                        if ((validateFn)(wtype, val) === false) {
                            isOk = false;
                            //return false;
                        }
                    }
                    if ($.isArray(val) && val.length > 0) {
                        for (var j = 0, len = val.length; j < len; j++) {
                            data.push(val[j]);
                        }
                    } else {
                        data.push({
                            key: itemInfo.entryPropertyNameOnly,
                            val: val
                        });
                    }
                }
            });
            if (!isOk) {
                if (errMessages.length > 0) rk.noticeError(errMessages[0]);
                return false;
            }
            var submit = data;
            return (submit.length == 0 ? null : submit);
        };
        me.getWidgetData = function(el, wtype){
            var refId = el.attr('refId');
            var itemInfo = itemsCache[refId + ''];
            var val, vals;
                switch (wtype) {
                        case 'span':
                        val = el.find('span:first').text();
                        break;
                        case '2':
                            val = el.find('textarea:first').val();
                            break;
                        case '3':
                            val = el.find('select:first').val();
                            break;
                        case '4':
                            var wtype_name = 'multiselect';
                            var checked = el.find('select')[wtype_name]('getChecked');
                            val = [];
                            checked.each(function(i, o) {
                                val.push($(o).attr('value'));
                            })
                            val = val.join(',');
                            break;
                        case '5':
                            val = el.find('input').numberInputPlus('getValue');
                            break;
                        case '6':
                            val = el.find('input').numberInputPlus('getValue');
                            break;
                        case '7':
                            var timepicker = el.find('input[act="timepicker"]');
                            //含日期
                            if (timepicker.size() > 0) {
                                vals = [{
                                    key: itemInfo.entryPropertyNameOnly,
                                    val: el.find('input[act="datepicker"]').val()
                                }, {
                                    key: itemInfo.entryPropertyNameOnly + '_time',
                                    val: timepicker.val()
                                }];
                            } else {
                                val = el.find('input[act="datepicker"]').val();
                            }
                            break;
                        case 'attachment':
                            var fileName = el.find('input[id="uploadingfileName"]').val();
                            var fileUrl = el.find('input[id="uploadingfileUrl"]').val();
                            vals = [{
                                key: 'fileName',
                                val: fileName
                            }, {
                                key: 'fileUrl',
                                val: fileUrl
                            }];
                            break;
                        default:
                            val = el.find('input').val();
                    }
            return $.isArray(vals) ? vals : val;
        };

        var validate = function(refId, wtype, value) {
            var itemInfo = itemsCache[refId + ''];
            if (itemInfo.must) {
                var ok = true;
                if (!$.isNumeric(value) && !value) {
                    ok = false;
                } else if (!$.isNumeric(value) && !$.trim(value)) {
                    ok = false;
                } else if ($.isArray(value) || value.length == 0) {
                    ok = false;
                }
                if (!ok) {
                    errMessages.push(rk.i18n('RKFORM_NEED_CORRECT_INPUT', itemInfo.itemName));
                    return false;
                }
            }
            return true;
        }

        module.exports = formService;
    })();
});
